package se.rende.myrss;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Locale;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerConfigurationException;

import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

import se.rende.myrss.data.Channel;
import se.rende.myrss.data.ChannelFilter;
import se.rende.myrss.data.ChannelItem;
import se.rende.myrss.data.DataService;
import se.rende.myrss.data.Filter;
import se.rende.myrss.data.FilterType;

@SuppressWarnings("serial")
public class DbServlet extends HttpServlet {
	private static final SimpleDateFormat headerDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
	private DataService data;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		try {
			data = new DataService();
			config.getServletContext().setAttribute("data", data);
		} catch (TransformerConfigurationException e) {
			throw new ServletException("Can't initialize data service", e);
		} catch (SAXNotRecognizedException e) {
			throw new ServletException("Can't initialize data service", e);
		} catch (SAXNotSupportedException e) {
			throw new ServletException("Can't initialize data service", e);
		}
	}

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setContentType("text/plain");
		resp.setCharacterEncoding("utf-8");
		PrintWriter w = resp.getWriter();
		
		String pathInfo = req.getPathInfo();
		if ("/addchannel".equals(pathInfo)) {
			String name = req.getParameter("name");
			String url = req.getParameter("url");
			if (name == null || url == null) {
				resp.setStatus(500);
			} else {
				data.addChannel(name, url);
			}
		} else if ("/rmchannel".equals(pathInfo)) {
			String id = req.getParameter("id");
			if (id == null) {
				resp.setStatus(500);
			} else {
				data.deleteChannel(Long.parseLong(id));
			}
		} else if ("/listchannels".equals(pathInfo)) {
			w.println("<?xml version='1.0' encoding='utf-8'?>");
			w.println("<channel>");
			for (Channel filterType : data.getChannels()) {
				w.println("  <channel id='" + filterType.getId() + "'  name='" + filterType.getName() + "' url='" + filterType.getUrl() + "'/>");
			}
			w.println("</channel>");
		} else if ("/listitems".equals(pathInfo)) {
			String channelIdString = req.getParameter("channel");
			long channelId = channelIdString == null ? 0 : Long.parseLong(channelIdString);
			w.println("<?xml version='1.0' encoding='utf-8'?>");
			w.println("<items>");
			for (ChannelItem item : data.getItems(channelId)) {
				w.println("  <item" +
					" id='" + item.getId() + "' " +
					" channel='" + item.getChannelId() + "' " +
					" title='" + item.getTitle() + "' " +
					" link='" + item.getLink() + "'" +
					" author='" + item.getAuthor() + "'" +
					" date='" + headerDateFormat.format(item.getDate()) + "'" +
					" description='" + item.getDescription() + "'" +
					"/>");
			}
			w.println("</items>");
		} else if ("/listfiltertypes".equals(pathInfo)) {
			w.println("<?xml version='1.0' encoding='utf-8'?>");
			w.println("<filtertypes>");
			for (FilterType filterType : data.getFilterTypes()) {
				w.println("  <filtertype id='" + filterType.getId() + "'/>");
			}
			w.println("</filtertypes>");
		} else if ("/listfilters".equals(pathInfo)) {
			w.println("<?xml version='1.0' encoding='utf-8'?>");
			w.println("<filters>");
			for (Filter filter : data.getFilters()) {
				w.println("  <filter" +
						" id='" + filter.getId() + "'" +
						" name='" + filter.getName() + "'" +
						" type='" + filter.getType().getId() + "'" +
						"/>");
			}
			w.println("</filters>");
		} else if ("/listchfilters".equals(pathInfo)) {
			w.println("<?xml version='1.0' encoding='utf-8'?>");
			w.println("<channelfilters>");
			for (ChannelFilter channelFilter : data.getChannelFilters()) {
				w.println("  <channelfilter" +
						" url='" + channelFilter.getUrl() + "'" +
						" filter='" + channelFilter.getFilter().getId() + "'" +
						"/>");
			}
			w.println("</channelfilters>");
		} else if ("/addchfilter".equals(pathInfo)) {
			String channelUrl = req.getParameter("ch");
			String filterId = req.getParameter("filter");
			Filter filter = findFilterById(filterId);
			if (channelUrl == null || filterId == null || filter == null) {
				resp.setStatus(500);
			} else {
				data.getChannelFilters().add(new ChannelFilter(channelUrl, filter));
			}
		} else {
			resp.setStatus(500);
		}
		
		w.close();
	}

	private Filter findFilterById(String filterId) {
		for (Filter filter : data.getFilters()) {
			if (filterId != null && filterId.equals(filter.getId())) {
				return filter;
			}
		}
		return null;
	}
}
